package top.zywork.service.impl;

import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import top.zywork.common.PageQueryUtils;
import top.zywork.common.TransactionNoGenerator;
import top.zywork.dao.*;
import top.zywork.dos.*;
import top.zywork.dto.PagerDTO;
import top.zywork.enums.*;
import top.zywork.query.GoodsOrderItemQuery;
import top.zywork.query.PageQuery;
import top.zywork.query.UserPathQuery;
import top.zywork.query.UserUserSocialQuery;
import top.zywork.service.DistributionService;
import top.zywork.service.PayService;
import top.zywork.service.SysConfigService;
import top.zywork.vo.ResponseStatusVO;
import top.zywork.weixin.PayConstants;
import top.zywork.weixin.RedpackSceneEnum;

import java.math.BigDecimal;
import java.util.*;

/**
 * 分销Service接口实现类<br/>
 *
 * 创建于2018-12-28<br/>
 *
 * @author 王振宇
 * @version 1.0
 */
@Service
@Slf4j
public class DistributionServiceImpl implements DistributionService {

    private static final int BEGIN_BELOW_LEVEL = 2;

    private DistributionDAO distributionDAO;

    private SysConfigService sysConfigService;

    private PayService payService;

    private UserUserSocialDAO userUserSocialDAO;

    private GoodsOrderItemDAO goodsOrderItemDAO;

    private GoodsCommissionDAO goodsCommissionDAO;

    private GoodsOrderDAO goodsOrderDAO;

    private UserRoleDAO userRoleDAO;

    private UserHierarchyDAO userHierarchyDAO;

    private UserPathDAO userPathDAO;

    @Override
    public DistributionUserDO getTheTop(Long userId) {
        return distributionDAO.getTheTop(userId);
    }

    @Override
    public PagerDTO listAllTop(Object queryObj) {
        PagerDTO pagerDTO = new PagerDTO();
        Long count = distributionDAO.countAllTop();
        pagerDTO.setTotal(count);
        if (count > 0) {
            pagerDTO.setRows(distributionDAO.listAllTop(queryObj));
        } else {
            pagerDTO.setRows(new ArrayList<>());
        }
        return pagerDTO;
    }

    @Override
    public PagerDTO listAboveUsers(Long userId, Integer distributionLevel, Long[] levels, PageQuery pageQuery) {
        PagerDTO pagerDTO = new PagerDTO();
        Long count = distributionDAO.countAboveUsers(userId, distributionLevel, levels);
        pagerDTO.setTotal(count);
        if (count > 0) {
            pagerDTO.setRows(distributionDAO.listAboveUsers(userId, distributionLevel, levels, pageQuery));
        } else {
            pagerDTO.setRows(new ArrayList<>());
        }
        return pagerDTO;
    }

    @Override
    public PagerDTO listDirectAboveUsers(Long userId, Integer distributionLevel, Long level, PageQuery pageQuery) {
        PagerDTO pagerDTO = new PagerDTO();
        Long count = distributionDAO.countDirectAboveUsers(userId, distributionLevel, level);
        pagerDTO.setTotal(count);
        if (count > 0) {
            pagerDTO.setRows(distributionDAO.listDirectAboveUsers(userId, distributionLevel, level, pageQuery));
        } else {
            pagerDTO.setRows(new ArrayList<>());
        }
        return pagerDTO;
    }

    @Override
    public PagerDTO listBelowUsers(Long userId, Long[] levels, PageQuery pageQuery) {
        PagerDTO pagerDTO = new PagerDTO();
        Long count = distributionDAO.countBelowUsers(userId, levels);
        pagerDTO.setTotal(count);
        if (count > 0) {
            pagerDTO.setRows(distributionDAO.listBelowUsers(userId, levels, pageQuery));
        } else {
            pagerDTO.setRows(new ArrayList<>());
        }
        return pagerDTO;
    }

    @Override
    public PagerDTO listDirectBelowUsers(Long userId, Long level, PageQuery pageQuery) {
        PagerDTO pagerDTO = new PagerDTO();
        Long count = distributionDAO.countDirectBelowUsers(userId, level);
        pagerDTO.setTotal(count);
        if (count > 0) {
            pagerDTO.setRows(distributionDAO.listDirectBelowUsers(userId, level, pageQuery));
        } else {
            pagerDTO.setRows(new ArrayList<>());
        }
        return pagerDTO;
    }

    @Override
    public List<Long> countBelowUsersPerLevel(Long userId, Long[] levels) {
        return distributionDAO.countBelowUsersPerLevel(userId, levels);
    }

    @Override
    public void grantCommission(Long userId, String[] orderIdAndNoAry, MallCommissionGrantConfig mallCommissionGrantConfig, Long pickupUserId) {
        DefaultDistributionConfig defaultDistributionConfig = sysConfigService.getByName(SysConfigEnum.DEFAULT_DISTRIBUTION_CONFIG.getValue(), DefaultDistributionConfig.class);
        if (defaultDistributionConfig.getNormalDistribution()) {
            grantDistributorCommission(userId, orderIdAndNoAry, mallCommissionGrantConfig, defaultDistributionConfig);
        }
        if (defaultDistributionConfig.getFixedTopDistribution()) {
            grantTopDistributorCommission(userId, orderIdAndNoAry, mallCommissionGrantConfig, defaultDistributionConfig);
        }
        if (pickupUserId != null && defaultDistributionConfig.getPickupStationDistribution()) {
            grantPickupDistributorCommission(pickupUserId, orderIdAndNoAry, mallCommissionGrantConfig, defaultDistributionConfig);
        }
        clearOrderItemListMap(orderIdAndNoAry);
    }

    /**
     * 发放提货点佣金
     * @param pickupUserId
     * @param orderIdAndNoAry
     * @param mallCommissionGrantConfig
     * @param defaultDistributionConfig
     */
    private void grantPickupDistributorCommission(Long pickupUserId, String[] orderIdAndNoAry, MallCommissionGrantConfig mallCommissionGrantConfig, DefaultDistributionConfig defaultDistributionConfig) {
        if (!canGrantCommission(pickupUserId, mallCommissionGrantConfig.getPickupDistributionRoles())) {
            log.info("the user is not pickup distributor(no role), can not grant commission, user id: {}", pickupUserId);
            return;
        }
        String openid = getOpenid(pickupUserId, mallCommissionGrantConfig);
        for (String orderIdAndNo : orderIdAndNoAry) {
            Long orderId = Long.valueOf(orderIdAndNo.split("-")[0]);
            int amount = getAmount(pickupUserId, -1, orderId, defaultDistributionConfig);
            if (amount <= 0) {
                log.info("grant commission amount <= 0, stop!!!");
            }
            doGrant(orderIdAndNo, mallCommissionGrantConfig, pickupUserId,  openid, amount, "商城订单提货奖励，订单信息：");
        }
    }

    /**
     * 发放顶级分销商佣金
     * @param userId
     * @param orderIdAndNoAry
     * @param mallCommissionGrantConfig
     * @param defaultDistributionConfig
     */
    private void grantTopDistributorCommission(Long userId, String[] orderIdAndNoAry, MallCommissionGrantConfig mallCommissionGrantConfig, DefaultDistributionConfig defaultDistributionConfig) {
        DistributionUserDO distributionUserDO = getTheTop(userId);
        if (distributionUserDO != null) {
            Long distributorUserId = distributionUserDO.getUserId();
            if (!canGrantCommission(distributorUserId, mallCommissionGrantConfig.getTopDistributionRoles())) {
                log.info("the user is not top distributor(no role), can not grant commission, user id: {}", distributorUserId);
                return;
            }
            String openid = getOpenid(distributorUserId, mallCommissionGrantConfig);
            for (String orderIdAndNo : orderIdAndNoAry) {
                Long orderId = Long.valueOf(orderIdAndNo.split("-")[0]);
                int amount = getAmount(distributorUserId, 0, orderId, defaultDistributionConfig);
                if (amount <= 0) {
                    log.info("grant commission amount <= 0, stop!!!");
                }
                doGrant(orderIdAndNo, mallCommissionGrantConfig, distributorUserId,  openid, amount, "商城订单佣金，订单信息：");
            }
        }
    }

    /**
     * 发放分销商的佣金
     * @param userId
     * @param orderIdAndNoAry
     * @param mallCommissionGrantConfig
     * @param defaultDistributionConfig
     */
    private void grantDistributorCommission(Long userId, String[] orderIdAndNoAry, MallCommissionGrantConfig mallCommissionGrantConfig, DefaultDistributionConfig defaultDistributionConfig) {
        Integer distributionLevel = defaultDistributionConfig.getDistributionLevel();
        List<Object> distributionList = distributionDAO.listAboveUsers(userId, distributionLevel, getLevels(distributionLevel), PageQueryUtils.getPageQuery(1, distributionLevel - 1));
        if (distributionList != null && distributionList.size() > 0) {
            for (Object obj : distributionList) {
                DistributionUserDO distributionUserDO = (DistributionUserDO) obj;
                Long distributorUserId = distributionUserDO.getUserId();
                if (!canGrantCommission(distributorUserId, mallCommissionGrantConfig.getDistributionRoles())) {
                    // 如果用户没有可发放佣金的角色，则不需要发放佣金
                    log.info("the user is not distributor, can not grant commission, user id: {}", distributorUserId);
                    continue;
                }
                String openid = getOpenid(distributorUserId, mallCommissionGrantConfig);
                for (String orderIdAndNo : orderIdAndNoAry) {
                    Long orderId = Long.valueOf(orderIdAndNo.split("-")[0]);
                    int amount = getAmount(distributorUserId, distributionUserDO.getLevel(), orderId, defaultDistributionConfig);
                    if (amount <= 0) {
                        log.info("grant commission amount <= 0, stop!!!");
                    }
                    doGrant(orderIdAndNo, mallCommissionGrantConfig, distributorUserId, openid, amount, "商城订单佣金，订单信息：");
                }
            }
        }
    }

    /**
     * 发放佣金到指定用户
     * @param orderIdAndNo 订单编号和订单号
     * @param mallCommissionGrantConfig 佣金发放配置类
     * @param distributorUserId 收款方，分销商用户id
     * @param openid 收款方openid
     * @param amount 收款金额，分
     */
    private void doGrant(String orderIdAndNo, MallCommissionGrantConfig mallCommissionGrantConfig, Long distributorUserId, String openid, int amount, String accountRemark) {
        log.info("begin to grant commission: orderIdAndNo: {}, to user: {}, amount: {}", orderIdAndNo, distributorUserId, amount);
        if (CommissionPayTypeEnum.PAY_BY_BALANCE.getValue().equals(mallCommissionGrantConfig.getCommissionPayType())) {
            // 通过余额发放佣金
            payService.transferByBalance(distributorUserId, TransactionNoGenerator.generateNo(), amount,
                    FundsChangeTypeEnum.MALL_DISTRIBUTE_COMMISSION_IN, FundsChangeTypeEnum.MALL_DISTRIBUTE_COMMISSION_OUT, accountRemark + orderIdAndNo);
        } else if (CommissionPayTypeEnum.PAY_BY_WEIXIN_XCX_PERSONAL.getValue().equals(mallCommissionGrantConfig.getCommissionPayType())) {
            // 微信小程序企业付款，佣金转账到个人，1元到20000元间可正常发送
            if (amount >= PayConstants.TRANSFER_MIN_AMOUNT && amount <= PayConstants.TRANSFER_MAX_AMOUNT) {
                payService.transferToPersonalXcx(distributorUserId, openid, "127.0.0.1", TransactionNoGenerator.generateNo(), amount,
                        "NO_CHECK", "商城订单佣金", "商城订单佣金，订单信息：" + orderIdAndNo,
                        FundsChangeTypeEnum.MALL_DISTRIBUTE_COMMISSION_IN, FundsChangeTypeEnum.MALL_DISTRIBUTE_COMMISSION_OUT);
            } else {
                payService.transferByBalance(distributorUserId, TransactionNoGenerator.generateNo(), amount,
                        FundsChangeTypeEnum.MALL_DISTRIBUTE_COMMISSION_IN, FundsChangeTypeEnum.MALL_DISTRIBUTE_COMMISSION_OUT, accountRemark + orderIdAndNo);
            }
        } else if (CommissionPayTypeEnum.PAY_BY_WEIXIN_GZH_PERSONAL.getValue().equals(mallCommissionGrantConfig.getCommissionPayType())) {
            // 微信公众号企业付款，佣金转账到个人，1元到20000元间可正常发送
            if (amount >= PayConstants.TRANSFER_MIN_AMOUNT && amount <= PayConstants.TRANSFER_MAX_AMOUNT) {
                payService.transferToPersonalGzh(distributorUserId, openid, "127.0.0.1", TransactionNoGenerator.generateNo(), amount,
                        "NO_CHECK", "商城订单佣金", "商城订单佣金，订单信息：" + orderIdAndNo,
                        FundsChangeTypeEnum.MALL_DISTRIBUTE_COMMISSION_IN, FundsChangeTypeEnum.MALL_DISTRIBUTE_COMMISSION_OUT);
            } else {
                payService.transferByBalance(distributorUserId, TransactionNoGenerator.generateNo(), amount,
                        FundsChangeTypeEnum.MALL_DISTRIBUTE_COMMISSION_IN, FundsChangeTypeEnum.MALL_DISTRIBUTE_COMMISSION_OUT, accountRemark + orderIdAndNo);
            }
        } else if (CommissionPayTypeEnum.PAY_BY_WEIXIN_GZH_REDPACK.getValue().equals(mallCommissionGrantConfig.getCommissionPayType())) {
            // 微信公众号红包转账，1-200元
            if (amount <= PayConstants.REDPACK_MAX_AMOUNT) {
                String sceneId = null;
                if (amount < PayConstants.REDPACK_MIN_AMOUNT) {
                    sceneId = RedpackSceneEnum.PRODUCT_5.getValue();
                }
                payService.sendRedpackByGzh(distributorUserId, openid, TransactionNoGenerator.generateNo(), "127.0.0.1", "商城佣金",
                        amount, 1, "恭喜发财", "", accountRemark + orderIdAndNo, sceneId,
                        FundsChangeTypeEnum.MALL_DISTRIBUTE_COMMISSION_IN, FundsChangeTypeEnum.MALL_DISTRIBUTE_COMMISSION_OUT);
            } else {
                payService.transferByBalance(distributorUserId, TransactionNoGenerator.generateNo(), amount,
                        FundsChangeTypeEnum.MALL_DISTRIBUTE_COMMISSION_IN, FundsChangeTypeEnum.MALL_DISTRIBUTE_COMMISSION_OUT, accountRemark + orderIdAndNo);
            }
        }
    }

    private Long[] getLevels(Integer distributionLevel) {
        Long[] levels = new Long[distributionLevel - 1];
        for (int i = 1; i < distributionLevel; i++) {
            levels[i - 1] = (long) i;
        }
        return levels;
    }

    /**
     * 判断用户是否为可发放佣金的角色
     * @param userId
     * @param roles
     * @return
     */
    private boolean canGrantCommission(Long userId, String roles) {
        if (StringUtils.isEmpty(roles)) {
            return false;
        }
        return userRoleDAO.hasRole(userId, roles.split(",")) > 0;
    }

    /**
     * 根据用户编号和佣金配置的发放方式去获取用户的openid
     * @param userId
     * @param mallCommissionGrantConfig
     * @return
     */
    private String getOpenid(Long userId, MallCommissionGrantConfig mallCommissionGrantConfig) {
        String openid = null;
        String socialType = null;
        if (CommissionPayTypeEnum.PAY_BY_WEIXIN_GZH_REDPACK.getValue().equals(mallCommissionGrantConfig.getCommissionPayType())
                || CommissionPayTypeEnum.PAY_BY_WEIXIN_GZH_PERSONAL.getValue().equals(mallCommissionGrantConfig.getCommissionPayType())) {
            socialType = SocialTypeEnum.WEIXIN_GZH.getValue();
        } else if (CommissionPayTypeEnum.PAY_BY_WEIXIN_XCX_REDPACK.getValue().equals(mallCommissionGrantConfig.getCommissionPayType())
                || CommissionPayTypeEnum.PAY_BY_WEIXIN_XCX_PERSONAL.getValue().equals(mallCommissionGrantConfig.getCommissionPayType())) {
            socialType = SocialTypeEnum.WEIXIN_XCX.getValue();
        }
        if (socialType != null) {
            List<Object> userObjList = userUserSocialDAO.listAllByCondition(UserUserSocialQuery.builder().userId(userId).userSocialSocialType(socialType).build());
            if (userObjList != null && userObjList.size() > 0) {
                openid = ((UserUserSocialDO) userObjList.get(0)).getUserSocialOpenid();
            }
        }
        return openid;
    }


    private Map<String, List<Object>> orderItemListMap = new HashMap<>();
    /**
     * 获取指定订单的佣金总金额
     * @param userId 接收佣金的用户编号
     * @param distributionLevel 佣金分销级别
     * @param orderId
     * @param defaultDistributionConfig
     * @return
     */
    private int getAmount(Long userId, int distributionLevel, Long orderId, DefaultDistributionConfig defaultDistributionConfig) {
        int amount = 0;
        List<Object> orderItemList;
        if (orderItemListMap.containsKey(orderId + "")) {
            orderItemList = orderItemListMap.get(orderId + "");
        } else {
            orderItemList = goodsOrderItemDAO.listAllByCondition(GoodsOrderItemQuery.builder().orderId(orderId).build());
            orderItemListMap.put(orderId + "", orderItemList);
        }
        if (orderItemList != null && orderItemList.size() > 0) {
            for (Object orderItemObj : orderItemList) {
                GoodsOrderItemDO goodsOrderItemDO = (GoodsOrderItemDO) orderItemObj;
                BigDecimal commissionPercent = goodsCommissionDAO.getCommissionPercent(userId, goodsOrderItemDO.getGoodsId(),
                        goodsOrderItemDO.getGoodsSkuId(), distributionLevel);
                if (commissionPercent == null) {
                    // 商品或SKU都没有配置分销比例，则使用默认分销比例，如果没有配置默认分销比例，则不分销
                    Double percent = distributionLevel == -1 ? defaultDistributionConfig.getPickupProfitPercent()
                            : distributionLevel == 0 ? defaultDistributionConfig.getTopProfitPercent()
                            : defaultDistributionConfig.getProfitPercents().get("level" + distributionLevel);
                    commissionPercent = percent == null ? null : new BigDecimal(percent);
                }
                if (commissionPercent != null) {
                    amount += goodsOrderItemDO.getPayAmount().multiply(commissionPercent).intValue();
                }
            }
        }
        return amount;
    }

    private void clearOrderItemListMap(String[] orderIdAndNoAry) {
        for (String orderIdAndNo : orderIdAndNoAry) {
            String orderId = orderIdAndNo.split("-")[0];
            orderItemListMap.remove(orderId);
        }
    }

    @Override
    public void saveDistributionUserRole(Long userId, Long[] orderIds) {
        DefaultDistributionConfig defaultDistributionConfig = sysConfigService.getByName(SysConfigEnum.DEFAULT_DISTRIBUTION_CONFIG.getValue(), DefaultDistributionConfig.class);
        if (DistributionAgentTypeEnum.NONE.getValue().equals(defaultDistributionConfig.getDistributionAgentType())) {
            // 不需要分销功能
        } else if (DistributionAgentTypeEnum.ANY_GOODS.getValue().equals(defaultDistributionConfig.getDistributionAgentType())) {
            // 购买何意商品成为分销商
            userRoleDAO.saveByRoleTitle(userId, defaultDistributionConfig.getDefaultAgentRole());
        } else if (DistributionAgentTypeEnum.SPECIFIC_GOODS.getValue().equals(defaultDistributionConfig.getDistributionAgentType())) {
            // 购买指定商品成为分销商
            for (Long orderId : orderIds) {
                String shopRemark = goodsOrderDAO.getShopRemarkByOrderId(orderId);
                if (StringUtils.isNotEmpty(shopRemark) && shopRemark.contains(":")) {
                    String agentRole = shopRemark.substring(shopRemark.lastIndexOf(":") + 1, shopRemark.length() - 1);
                    userRoleDAO.saveByRoleTitle(userId, agentRole);
                }
            }
        }
    }

    @Override
    public Integer getMaxLevel(Long userId) {
        return distributionDAO.getMaxLevel(userId);
    }

    @Override
    public Long countAllBelowUsers(Long userId) {
        return distributionDAO.countAllBelowUsers(userId);
    }

    @Override
    public BigDecimal countMallBelowPerformance(Long userId, Long[] levels, Date beginTime, Date endTime) {
        List<Object> objList = distributionDAO.listBelowUsers(userId, levels, PageQueryUtils.getPageQuery(1, 100000));
        if (objList != null) {
            int size = objList.size();
            Long[] userIds = new Long[objList.size()];
            for (int i = 0; i < size; i++) {
                DistributionUserDO distributionUserDO = (DistributionUserDO) objList.get(i);
                userIds[i] = distributionUserDO.getUserId();
            }
            BigDecimal amount = goodsOrderDAO.countAllAmount(userIds, getOrderStatus(), beginTime, endTime);;
            return amount == null ? new BigDecimal(0) : amount;
        }
        return new BigDecimal(0);
    }

    @Override
    public BigDecimal countMallAllBelowPerformance(Long userId, Date beginTime, Date endTime) {
        int maxLevel = distributionDAO.getMaxLevel(userId);
        if (maxLevel > 0) {
            Long[] levels = new Long[maxLevel];
            for (int i = BEGIN_BELOW_LEVEL; i <= maxLevel + 1; i++) {
                levels[i - BEGIN_BELOW_LEVEL] = (long) i;
            }
            List<Object> objList = distributionDAO.listBelowUsers(userId, levels, PageQueryUtils.getPageQuery(1, 100000));
            if (objList != null) {
                int size = objList.size();
                Long[] userIds = new Long[objList.size()];
                for (int i = 0; i < size; i++) {
                    DistributionUserDO distributionUserDO = (DistributionUserDO) objList.get(i);
                    userIds[i] = distributionUserDO.getUserId();
                }
                BigDecimal amount = goodsOrderDAO.countAllAmount(userIds, getOrderStatus(), beginTime, endTime);
                return amount == null ? new BigDecimal(0) : amount;
            }
        }
        return new BigDecimal(0);
    }

    /**
     * 获取计算业绩的订单状态，包含两种情况：付款成功即计算业绩，确认收货即计算业绩
     * @return
     */
    private byte getOrderStatus() {
        byte orderStatus = -1;
        MallCommissionGrantConfig mallCommissionGrantConfig = sysConfigService.getByName(SysConfigEnum.MALL_COMMISSION_GRANT_CONFIG.getValue(), MallCommissionGrantConfig.class);
        if (mallCommissionGrantConfig.getPayOrder() && !mallCommissionGrantConfig.getConfirmOrder()) {
            // 明确设置了付款时发放而确认收货时不发放，则只要付款了就计算业绩
            orderStatus = GoodsOrderStatusEnum.WAIT_DELIVER.getValue().byteValue();
        } else {
            // 确认收货才计算业绩
            orderStatus = GoodsOrderStatusEnum.CONFIRMED.getValue().byteValue();
        }
        return orderStatus;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public ResponseStatusVO putToTop(Long userId) {
        Long isTop = distributionDAO.isTop(userId);
        if (isTop == 1) {
            return ResponseStatusVO.dataError("此用户已经是顶级分销商，无需重复操作", null);
        }
        UserPathQuery userPathQuery = UserPathQuery.builder().userPath("/" + userId).build();
        userPathQuery.setSortColumn("userPath");
        userPathQuery.setSortOrder("asc");
        List<Object> userPathList = userPathDAO.listAllByCondition(userPathQuery);
        List<Object> newUserPathDOList = new ArrayList<>();
        List<String> toDeleteUserHierarchyList = new ArrayList<>();
        for (Object obj : userPathList) {
            UserPathDO userPathDO = (UserPathDO) obj;
            String userPath = userPathDO.getUserPath();
            int index = userPath.indexOf("/" + userId);
            // 获取所有新的用户路径
            userPathDO.setUserPath(userPath.substring(index));
            newUserPathDOList.add(userPathDO);

            String frontUserPath = userPath.substring(0, index);
            String backUserPath = userPath.substring(index);
            String[] backUserIdAry = backUserPath.substring(1).split("/");
            if (StringUtils.isNotEmpty(frontUserPath)) {
                String[] frontUserIdAry = frontUserPath.substring(1).split("/");
                // 获取需要删除的用户关系
                for (String frontUserId : frontUserIdAry) {
                    for (String backUserId : backUserIdAry) {
                        String toDelete = frontUserId + "," + backUserId;
                        if (!toDeleteUserHierarchyList.contains(toDelete)) {
                            toDeleteUserHierarchyList.add(toDelete);
                        }
                    }
                }
            }
        }
        // 更新用户路径
        userPathDAO.updateBatch(newUserPathDOList);
        // 删除解除的用户关系
        for (String toDeleteUserHierarchy : toDeleteUserHierarchyList) {
            String[] userIds = toDeleteUserHierarchy.split(",");
            userHierarchyDAO.removeUserHierarchy(Long.parseLong(userIds[0]), Long.parseLong(userIds[1]));
        }
        return ResponseStatusVO.ok("已设置为顶级分销商", null);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public ResponseStatusVO putToUser(Long userId, Long toUserId) {
        Long isDirect = distributionDAO.isDirect(toUserId, userId);
        if (isDirect == 1) {
            return ResponseStatusVO.dataError("已经是上下级关系，无需重复操作", null);
        }
        UserPathQuery toUserPathQuery = UserPathQuery.builder().userPath("/" + toUserId).build();
        toUserPathQuery.setSortColumn("userPath");
        toUserPathQuery.setSortOrder("asc");
        toUserPathQuery.setPageNo(1);
        toUserPathQuery.setPageSize(1);
        List<Object> toUserPathList = userPathDAO.listPageByCondition(toUserPathQuery);
        if (toUserPathList == null || toUserPathList.isEmpty()) {
            return ResponseStatusVO.dataError("指定的上级用户不存在", null);
        }
        UserPathDO toUserPathDO = (UserPathDO) toUserPathList.get(0);
        UserPathQuery userPathQuery = UserPathQuery.builder().userPath("/" + userId).build();
        userPathQuery.setSortColumn("userPath");
        userPathQuery.setSortOrder("asc");
        List<Object> userPathList = userPathDAO.listAllByCondition(userPathQuery);
        List<Object> newUserPathDOList = new ArrayList<>();
        List<String> toDeleteUserHierarchyList = new ArrayList<>();
        List<Object> toSaveUserHierarchyList = new ArrayList<>();
        List<String> toSaveAncestorUserIdList = new ArrayList<>();
        String[] toUserIdAry = toUserPathDO.getUserPath().substring(1).split("/");
        for (Object obj : userPathList) {
            UserPathDO userPathDO = (UserPathDO) obj;
            String userPath = userPathDO.getUserPath();
            int index = userPath.indexOf("/" + userId);
            // 获取所有新的用户路径
            userPathDO.setUserPath(toUserPathDO.getUserPath() + userPath.substring(index));
            newUserPathDOList.add(userPathDO);

            String frontUserPath = userPath.substring(0, index);
            String backUserPath = userPath.substring(index);
            String[] backUserIdAry = backUserPath.substring(1).split("/");
            if (StringUtils.isNotEmpty(frontUserPath)) {
                String[] frontUserIdAry = frontUserPath.substring(1).split("/");
                // 获取需要删除的用户关系
                for (String frontUserId : frontUserIdAry) {
                    for (String backUserId : backUserIdAry) {
                        String toDelete = frontUserId + "," + backUserId;
                        if (!toDeleteUserHierarchyList.contains(toDelete)) {
                            toDeleteUserHierarchyList.add(toDelete);
                        }
                    }
                }
            }
            // 获取需要重新保存的用户关系
            int beginLevel = 2;
            for (int i = toUserIdAry.length - 1; i >= 0; i--) {
                for (int j = 0, len = backUserIdAry.length; j < len; j++) {
                    String ancestorId = toUserIdAry[i];
                    String backUserId = backUserIdAry[j];
                    String savedIds = ancestorId + "," + backUserId;
                    if (!toSaveAncestorUserIdList.contains(savedIds)) {
                        toSaveAncestorUserIdList.add(savedIds);
                        toSaveUserHierarchyList.add(UserHierarchyDO.builder()
                                .ancestorId(Long.parseLong(ancestorId))
                                .userId(Long.parseLong(backUserId))
                                .userLevel(beginLevel + j)
                                .build());
                    }
                }
                beginLevel++;
            }
        }
        // 更新用户路径
        userPathDAO.updateBatch(newUserPathDOList);
        // 删除解除的用户关系
        for (String toDeleteUserHierarchy : toDeleteUserHierarchyList) {
            String[] userIds = toDeleteUserHierarchy.split(",");
            userHierarchyDAO.removeUserHierarchy(Long.parseLong(userIds[0]), Long.parseLong(userIds[1]));
        }
        // 保存新的用户关系
        userHierarchyDAO.saveBatch(toSaveUserHierarchyList);
        return ResponseStatusVO.ok("已重设此用户的直接上线", null);
    }

    @Autowired
    public void setDistributionDAO(DistributionDAO distributionDAO) {
        this.distributionDAO = distributionDAO;
    }

    @Autowired
    public void setSysConfigService(SysConfigService sysConfigService) {
        this.sysConfigService = sysConfigService;
    }

    @Autowired
    public void setPayService(PayService payService) {
        this.payService = payService;
    }

    @Autowired
    public void setUserUserSocialDAO(UserUserSocialDAO userUserSocialDAO) {
        this.userUserSocialDAO = userUserSocialDAO;
    }

    @Autowired
    public void setGoodsOrderItemDAO(GoodsOrderItemDAO goodsOrderItemDAO) {
        this.goodsOrderItemDAO = goodsOrderItemDAO;
    }

    @Autowired
    public void setGoodsCommissionDAO(GoodsCommissionDAO goodsCommissionDAO) {
        this.goodsCommissionDAO = goodsCommissionDAO;
    }

    @Autowired
    public void setGoodsOrderDAO(GoodsOrderDAO goodsOrderDAO) {
        this.goodsOrderDAO = goodsOrderDAO;
    }

    @Autowired
    public void setUserRoleDAO(UserRoleDAO userRoleDAO) {
        this.userRoleDAO = userRoleDAO;
    }

    @Autowired
    public void setUserHierarchyDAO(UserHierarchyDAO userHierarchyDAO) {
        this.userHierarchyDAO = userHierarchyDAO;
    }

    @Autowired
    public void setUserPathDAO(UserPathDAO userPathDAO) {
        this.userPathDAO = userPathDAO;
    }
}
